package ling.common;

import cn.hutool.core.date.DateUtil;
import com.easy.query.api.proxy.entity.select.EntityQueryable;
import com.easy.query.api4j.select.Queryable;
import com.easy.query.api4j.sql.SQLWherePredicate;
import com.easy.query.core.api.dynamic.sort.ObjectSort;
import com.easy.query.core.api.pagination.EasyPageResult;
import com.easy.query.core.expression.lambda.SQLExpression1;
import com.easy.query.core.proxy.ProxyEntity;
import com.easy.query.core.proxy.ProxyEntityAvailable;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.utils.poi.ExcelUtil;
import ling.common.domain.PageSort;
import ling.common.domain.Result;
import ling.common.domain.ResultRows;
import ling.common.domain.entity.CU2Entity;
import ling.common.domain.entity.CreatedEntity;
import ling.common.domain.entity.IdEntity;
import lombok.var;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.ResolvableType;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * EQueryController;
 * @author : He-LiangLiang@Outlook.com
 * @date : 2025-3-26
 */
public abstract class EQueryController<T extends IdEntity> extends BaseController {
    @Resource
    protected EQueryHelper queryHelper;
   protected Queryable<T> equeryable() {
       return queryHelper.query().queryable(tClass);
   }

    final protected Class<T> tClass= (Class<T>) ResolvableType.forClass(getClass()).getSuperType().getGeneric(0).resolve();

    public Page toPageData(EasyPageResult pData) {
        return new PageImpl<>(pData.getData(), Pageable.unpaged(), pData.getTotal());
    }
    public Page toPageData(List list) {
        return new PageImpl<>(list, Pageable.unpaged(), list.size());
    }
    public Page toPageData(List list,Long total) {
        return new PageImpl<>(list, Pageable.unpaged(), total);
    }

    public <L> ResultRows<L> toResultRows(EasyPageResult<L> page){
      return   new ResultRows<L>(page.getTotal(),page.getData());
    }
    protected ResultRows<T> queryPage(Serializable whereObj, PageDomain pageRequest) {
        if (pageRequest == null) {
            var pData = queryHelper.queryable(tClass)
                    .whereObject(whereObj != null, whereObj)
                    .toList();
            return new ResultRows<>(pData.size(), pData);
        }

        gainPageDomain(pageRequest);
        var pitem = queryHelper.query().queryable(tClass)
                .whereObject(whereObj != null, whereObj);
        if (pageRequest instanceof ObjectSort)
            pitem.orderByObject((ObjectSort) pageRequest);
        var pData = pitem.orderByDesc(p->p.column(T::getId)).toPageResult(pageRequest.getPageNum(), pageRequest.getPageSize());
        return toResultRows(pData);
    }
    protected ResultRows<T> queryPage(Serializable whereObj, PageDomain pageRequest, SQLExpression1<SQLWherePredicate<T>> whereExpression) {
        if (pageRequest == null) {
            var pData = queryHelper.queryable(tClass)
                    .where(whereExpression!=null,whereExpression)
                    .whereObject(whereObj != null, whereObj)
                    .toList();
            return new ResultRows<>(pData.size(), pData);
        }

        gainPageDomain(pageRequest);
        var pitem = queryHelper.query().queryable(tClass)
                .where(whereExpression!=null,whereExpression)
                .whereObject(whereObj != null, whereObj);
        if (pageRequest instanceof ObjectSort)
            pitem.orderByObject((ObjectSort) pageRequest);
        var pData = pitem.orderByDesc(p->p.column(T::getId)).toPageResult(pageRequest.getPageNum(), pageRequest.getPageSize());
        return toResultRows(pData);
    }

   protected PageDomain gainPageDomain(PageDomain pageRequest) {
        if (pageRequest == null)
            pageRequest = new PageDomain();
        if (pageRequest.getPageSize() == null)
            pageRequest.setPageSize(10);
        if (pageRequest.getPageNum() == null)
            pageRequest.setPageNum(1);
        return pageRequest;
    }

    public Result<T> getInfo(Object id)
    {
        return Result.ok(equeryable().whereById(id).firstOrNull());
    }
    /**
     * 导出班子记录列表
     */

    //@Log(title = "班子记录", businessType = BusinessType.EXPORT)
    protected void export(Serializable entity, PageDomain pageRequest,String fileName,HttpServletResponse response)
    {
        pageRequest.setPageNum(1);
        pageRequest.setPageSize(Integer.MAX_VALUE);
        List<T> list = queryPage(entity,pageRequest).getRows();
        ExcelUtil<T> util = new ExcelUtil<T>(tClass);
        util.exportExcel(response, list, StringUtils.isBlank(fileName)?"数据记录_"+DateUtil.today():fileName);
    }
    protected Result<Long> add(@RequestBody T entity) {
        if(entity instanceof CreatedEntity) {
            var cu = ((CreatedEntity<?>) entity);
            if (cu.getCreatedTime() == null)
                cu.setCreatedTime(new Date());
            if (cu.getCreatedId() == null)
                cu.setCreatedId(getUserId());
        }
        var re = queryHelper.query().insertable(entity).executeRows(true);
        if (re > 0)
            return Result.ok(re);
        return Result.fail("添加失败");
    }
    protected Result<Long> add(List<T> entitys) {
        for (var entity : entitys) {
            if (entity instanceof CreatedEntity) {
                var cu = ((CreatedEntity<?>) entity);
                if (cu.getCreatedTime() == null)
                    cu.setCreatedTime(new Date());
                if (cu.getCreatedId() == null)
                    cu.setCreatedId(getUserId());
            }
        }
        var re = queryHelper.query().insertable(entitys).executeRows(true);
        if (re > 0)
            return Result.ok(re);
        return Result.fail("添加失败");
    }


    protected Result<Long> remove(T entity){
        var re= queryHelper.query().deletable(entity)
                .disableLogicDelete().allowDeleteStatement(true)
                .executeRows();
        return Result.ok(re);
    }

    protected Result<Long> remove(Object[] ids) {

        var count = queryHelper.query().deletable(tClass)
                .disableLogicDelete().allowDeleteStatement(true)
                .whereByIds(Arrays.asList(ids)).executeRows();
        if (ids.length != count)
            logger.warn("批量删除异常", (Object[]) ids);
        return Result.ok(count);
    }


     protected Result<Long> edit(@RequestBody T entity) {
        if(entity instanceof CU2Entity)
        {
             var cu=((CU2Entity<?>) entity);
             cu.setUpdatedTime(new Date());
             cu.setUpdatedId(getUserId());
        }
        var re = queryHelper.query().updatable(entity).executeRows();
        if (re > 0)
            return Result.ok(re);
        return Result.fail("更新失败");
    }

}
